package com.jl.util;

public class LengthUtil {

	public static String replace(String data) {
		return cx(sx(bx(xx(data))));
	}

	/**
	 * replace the xx in the string
	 * 
	 * @param data
	 * @return
	 */
	public static String xx(String data) {
		data = data.toUpperCase();
		int index = data.lastIndexOf("XX");
		if (index == -1) {
			return data;
		} else {
			String temp = data.substring(index + 2);
			int count = getCount(temp);
			String len = getLength(count);
			data = data.substring(0, index) + len + temp;
			return xx(data);
		}
	}

	/**
	 * get the length with the 8x
	 * 
	 * @param count
	 * @return
	 */
	public static String getLength(int count) {
		String res = "";
		if (count <= 127) {
			res = HexUtil.toHex(count, 1);
		} else if (count >= 128 && count <= 255) {
			res = "81" + HexUtil.toHex(count, 1);
		} else if (count >= 256 && count <= 65535) {
			res = "82" + HexUtil.toHex(count, 2);
		} else if (count >= 65536 && count <= 16777215) {
			res = "83" + HexUtil.toHex(count, 3);
		}
		return res;
	}

	/**
	 * get the length with the 8x
	 * 
	 * @param count
	 * @return
	 */
	public static byte[] getLengthArray(int count) {
		return HexUtil.parseHexToByteArray(getLength(count));
	}

	/**
	 * replace the bx in the string ,bx means the byte length. the 0xFF is the
	 * max value
	 * 
	 * @param data
	 * @return
	 */
	public static String bx(String data) {
		data = data.toUpperCase();
		int index = data.lastIndexOf("BX");
		if (index == -1) {
			return data;
		} else {
			String temp = data.substring(index + 2);
			int count = getCount(temp);
			String len = HexUtil.toHexXX(count);
			data = data.substring(0, index) + len + temp;
			return bx(data);
		}
	}

	/**
	 * replace the sx in the string ,sx means the short length. the 0xFFFF is
	 * the max value.
	 * 
	 * @param data
	 * @return
	 */
	public static String sx(String data) {
		data = data.toUpperCase();
		int index = data.lastIndexOf("SX");
		if (index == -1) {
			return data;
		} else {
			String temp = data.substring(index + 2);
			int count = getCount(temp);
			String len = HexUtil.toHex(count, 2);
			data = data.substring(0, index) + len + temp;
			return sx(data);
		}
	}

	/**
	 * cx means the command length ,is the lc field in the apdu.it must just
	 * apperance once.
	 * 
	 * @param data
	 * @return
	 */
	public static String cx(String data) {
		data = data.toUpperCase();
		int index = data.indexOf("CX");
		if (index == -1) {
			return data;
		} else {
			String temp = data.substring(index + 2);
			String len = HexUtil.toHexXX(getCount(temp));
			return data.replaceFirst("CX", len);
		}
	}

	/**
	 * get the string hex count,but the bx is also a hex and sx means two hex.
	 * 
	 * @param data
	 * @return
	 */
	private static int getCount(String data) {
		data = data.toUpperCase();
		int count = 0;
		for (int i = data.length() - 1; i >= 0; i--) {
			if (HexUtil.isHex(data.charAt(i))) {
				count++;
			} else if (data.charAt(i) == 'X') {
				if (data.charAt(i - 1) == 'B') {
					count += 2;
				} else if (data.charAt(i - 1) == 'S') {
					count += 4;
				}
				i -= 2;
			}
		}
		return count / 2;
	}
}
